// locutor
// (c) 2009, Normen Müller, normen.mueller@gmail.com  
// $Id: Util.scala 3 2009-11-06 19:37:06Z normen.mueller $
package locutor.spec

import java.text.MessageFormat.{format}

import scaup.Views._

object Util {
  val TMP = System.getProperty("java.io.tmpdir").toFile
  val HOME = System.getProperty("user.home").toFile
  val REG = TMP / "locutor.xml"
  val WCA = TMP/"wca"
  val WCB = TMP/"wcb"
  val WCC = TMP/"wcc"
  val WCD = TMP/"wcd"
  val WCE = TMP/"wce"
  val WCF = TMP/"wcf"
  val WCG = TMP/"wcg"
  val WCH = TMP/"wch"
  val URLA = "https://svn.kwarc.info/repos/sandbox/wca"
  val URLB = "https://svn.kwarc.info/repos/sandbox/wcb"
  val URLC = "https://svn.kwarc.info/repos/sandbox/wcc"
  val URLD = "https://svn.kwarc.info/repos/sandbox/wcd"
  val URLE = "https://svn.kwarc.info/repos/sandbox/wce"
  val URLF = "https://svn.kwarc.info/repos/sandbox/wcf"
  val URLG = "https://svn.kwarc.info/repos/sandbox/wcg"
  val URLH = "https://svn.kwarc.info/repos/sandbox/wch"
  
  def newRegistry() = {
    REG.remove()
    new locutor.registry.Registry(REG)
  }  
  def setupRegistry(xml: scala.xml.Node) = {
    REG.remove()
    scala.xml.XML.save(REG.path, xml)
    new locutor.registry.Registry(REG)
  }
  
  def setupWC(name: String): Unit = name match {
    case "wca" =>
      new Runnable() {def run() = println("       Setting up wca...")}.run
//      print("       Setting up wca...")
      resetWC("wca")
      ioMkDir("import/wca/a", "import/wca/b"); svnImport("import", "https://svn.kwarc.info/repos/sandbox", "")
      svnCheckout("https://svn.kwarc.info/repos/sandbox/wca", "wca")
//      println(" Done.")
      println("\033[1A\033[24C Done.");
    case "wcb" =>
      new Runnable() {def run() = println("       Setting up wcb...")}.run
//      print("       Setting up wcb...")
      resetWC("wcb")
      ioMkDir("import/wcb/b"); svnImport("import", "https://svn.kwarc.info/repos/sandbox", "")
      svnCheckout("https://svn.kwarc.info/repos/sandbox/wcb", "wcb")
      svnSetExternal("wcb", (-1, "https://svn.kwarc.info/repos/sandbox/wca", "a"))
      svnCommit("wcb", "")
//      println(" Done.")
      println("\033[1A\033[24C Done.");
    case "wcc" =>
      new Runnable() {def run() = println("       Setting up wcc...")}.run
//      print("       Setting up wcc...")
      resetWC("wcc")
      ioMkDir("import/wcc/b"); svnImport("import", "https://svn.kwarc.info/repos/sandbox", "")
      svnCheckout("https://svn.kwarc.info/repos/sandbox/wcc", "wcc")
      svnSetExternal("wcc", (-1, "https://svn.kwarc.info/repos/sandbox/wcb", "a"))
      svnCommit("wcc", "")
//      println(" Done.")
      println("\033[1A\033[24C Done.");
    case "wcd" =>
      new Runnable() {def run() = println("       Setting up wcd...")}.run
//      print("       Setting up wcd...")
      resetWC("wcd")
      ioMkDir("import/wcd/b"); svnImport("import", "https://svn.kwarc.info/repos/sandbox", "")
      svnCheckout("https://svn.kwarc.info/repos/sandbox/wcd", "wcd")
      svnSetExternal("wcd", (-1, "https://svn.kwarc.info/repos/sandbox/wca/a", "a"))
      svnCommit("wcd", "")
//      println(" Done.")
      println("\033[1A\033[24C Done.");
    case "wce" =>
      new Runnable() {def run() = println("       Setting up wce...")}.run
//      print("       Setting up wce...")      
      resetWC("wce")
      ioMkDir("import/wce/b"); svnImport("import", "https://svn.kwarc.info/repos/sandbox", "")
      svnCheckout("https://svn.kwarc.info/repos/sandbox/wce", "wce")
      svnSetExternal("wce", (-1, "https://svn.kwarc.info/repos/sandbox/wca", "a"))
      svnCommit("wce", "")
//      println(" Done.")
      println("\033[1A\033[24C Done.");
    case "wcf" =>
      new Runnable() {def run() = println("       Setting up wcf...")}.run
//      print("       Setting up wcf...")
      resetWC("wcf")
      ioMkDir("import/wcf"); svnImport("import", "https://svn.kwarc.info/repos/sandbox", "")
      svnCheckout("https://svn.kwarc.info/repos/sandbox/wcf", "wcf")
      svnSetExternal("wcf", (-1, "https://svn.kwarc.info/repos/sandbox/wca/a", "a"), (-1, "https://svn.kwarc.info/repos/sandbox/wca/b", "b"))
      svnCommit("wcf", "")
//      println(" Done.")
      println("\033[1A\033[24C Done.");
    case "wcg" =>
      new Runnable() {def run() = println("       Setting up wcg...")}.run
//      print("       Setting up wcg...")
      resetWC("wcg")
      ioMkDir("import/wcg/b"); svnImport("import", "https://svn.kwarc.info/repos/sandbox", "")
      svnCheckout("https://svn.kwarc.info/repos/sandbox/wcg", "wcg")
      svnSetExternal("wcg", (-1, "https://svn.kwarc.info/repos/sandbox/wcf", "a"))
      svnCommit("wcg", "")
//      println(" Done.")
      println("\033[1A\033[24C Done.");
    case "wch" =>      
      setupWC("wca")
      new Runnable() {def run() = println("       Setting up wch...")}.run
//      print("       Setting up wch...")
      resetWC("wch")      
      ioMkDir("import/wch/doc/macros", "import/wch/projects/dockon/doc")
      svnImport("import", "https://svn.kwarc.info/repos/sandbox", "")
      svnCheckout("https://svn.kwarc.info/repos/sandbox/wch", "wch")
      svnSetExternal("wch/doc/macros", (-1, URLA, "cm"))
      svnSetExternal("wch/projects/dockon/doc", (-1, "https://svn.kwarc.info/repos/sandbox/wch/doc/macros", "macros"))
      svnCommit("wch", "")
//      println(" Done.")
      println("\033[1A\033[24C Done.");
  }
  def resetWC(name: String): Unit = name match {
    case "wca" => svnRemove("https://svn.kwarc.info/repos/sandbox/wca", ""); ioRemove("import"); ioRemove("wca")
    case "wcb" => svnRemove("https://svn.kwarc.info/repos/sandbox/wcb", ""); ioRemove("import"); ioRemove("wcb")
    case "wcc" => svnRemove("https://svn.kwarc.info/repos/sandbox/wcc", ""); ioRemove("import"); ioRemove("wcc")
    case "wcd" => svnRemove("https://svn.kwarc.info/repos/sandbox/wcd", ""); ioRemove("import"); ioRemove("wcd")
    case "wce" => svnRemove("https://svn.kwarc.info/repos/sandbox/wce", ""); ioRemove("import"); ioRemove("wce")
    case "wcf" => svnRemove("https://svn.kwarc.info/repos/sandbox/wcf", ""); ioRemove("import"); ioRemove("wcf")
    case "wcg" => svnRemove("https://svn.kwarc.info/repos/sandbox/wcg", ""); ioRemove("import"); ioRemove("wcg")
    case "wch" => svnRemove("https://svn.kwarc.info/repos/sandbox/wch", ""); ioRemove("import"); ioRemove("wch")
  }
  def resetAllWC() {
    new Runnable() {def run() = println("       Resetting all working copies...")}.run
//    print("       Resetting all working copies...")
    resetWC("wca"); resetWC("wcb"); resetWC("wcc"); resetWC("wcd");
    resetWC("wce"); resetWC("wcf"); resetWC("wcg"); resetWC("wch");
    println("\033[1A\033[38C Done.");    
  }
  
  def ioRemove(paths: String*) = Runtime.getRuntime().exec(Array[String]("rm", "-rf") ++ (paths map (p => (TMP/p).ap))).waitFor
  def ioMkDir(paths: String*) = Runtime.getRuntime().exec(Array[String]("mkdir", "-p") ++ (paths map (p => (TMP/p).ap))).waitFor
  
  def svnImport(path: String, url: String, msg: String) = {
    Runtime.getRuntime().exec(Array[String]("svn", "--username", "nmueller", "import", (TMP/path).ap, url, "-m", msg)).waitFor()
    Thread.sleep(100)
  }
  def svnCheckout(url: String, path: String) = {
    Runtime.getRuntime().exec(Array[String]("svn",  "--username", "nmueller", "co", url, (TMP/path).ap)).waitFor
    Thread.sleep(100)
  }
  def svnRemove(url: String, msg: String) = {
    Runtime.getRuntime().exec(Array[String]("svn",  "--username", "nmueller", "rm", url, "-m", msg)).waitFor
    Thread.sleep(100)
  }
  def svnCommit(path: String, msg: String) = {
    Runtime.getRuntime().exec(Array[String]("svn",  "--username", "nmueller", "ci", "-m", msg, (TMP/path).ap)).waitFor
    Thread.sleep(100)
  }
  def svnUpdate(paths: String*) = {
    val msg = "       Updating " + (paths mkString) + " ..."
    new Runnable() {def run() = println(msg)}.run
//    print("       Updating " + (paths mkString) + " ...")
    Runtime.getRuntime().exec(Array[String]("svn",  "--username", "nmueller", "update") ++ (paths map (p => (TMP/p).ap))).waitFor
    Thread.sleep(100)
//    println(" Done.")
    println("\033[1A\033["+msg.length+"C Done.");
  }
  def svnSetExternal(target: String, extdef: (Long, String, String)*) {
    val buf = new StringBuilder
    for(e <- extdef) buf append e._3 append " "  append {if(e._1 > -1) "-r" + e._1 + " " else ""} append e._2 append "\n"
    Runtime.getRuntime().exec(Array[String]("svn",  "--username", "nmueller", "propset", "svn:externals", buf.toString(), (TMP/target).ap)).waitFor()
    Thread.sleep(100)
  }
}
